﻿Imports System.Runtime.InteropServices
Imports System.Text
Public Module ModTool
    Public ASCII As Encoding = Encoding.ASCII 'ASCII编码
    Public gASCII As Encoding = Encoding.ASCII 'ASCII编码
    Public gEncDefault As Encoding = Encoding.Default '默认编码
    Private mHexDigits() As Byte = gASCII.GetBytes("0123456789ABCDEF") '字节转十六进制时十六进制字符串代码表
    Private mByteDigits() As Byte '十六进制转字节，十六进制每个字符对应的码值表
    Public UTF8 As Encoding = Encoding.UTF8

    ''' <summary>
    ''' 可处理12个字节的大数据类型
    ''' </summary>
    <StructLayout(LayoutKind.Explicit)>
    Public Structure BigInt
        <FieldOffset(0)>
        Public BigValue As Decimal

        ''' <summary>
        ''' 小数点精度
        ''' </summary>
        <FieldOffset(2)>
        Public FloatDigit As Byte

        ''' <summary>
        ''' 符号位  0--正数，0x80--负数
        ''' </summary>
        <FieldOffset(3)>
        Public Negative As Byte

        ''' <summary>
        ''' 前4字节
        ''' </summary>
        <FieldOffset(4)>
        Public UIntHeadValue As UInt32
        ''' <summary>
        ''' 前4字节
        ''' </summary>
        <FieldOffset(4)>
        Public IntHeadValue As Int32

        ''' <summary>
        ''' 后8字节
        ''' </summary>
        <FieldOffset(8)>
        Public Int64Value As Long
        ''' <summary>
        ''' 后8字节
        ''' </summary>
        <FieldOffset(8)>
        Public UInt64Value As ULong


        ''' <summary>
        ''' 后4字节
        ''' </summary>
        <FieldOffset(8)>
        Public Int32Value As Integer
        ''' <summary>
        ''' 后4字节
        ''' </summary>
        <FieldOffset(8)>
        Public UInt32Value As UInteger


        Public Function toBytes() As Byte()
            Dim bByte(11) As Byte
            Dim iAndValue As ULong = 255
            Dim lValue = UInt64Value
            For i = 11 To 4 Step -1
                bByte(i) = CByte(lValue And iAndValue)

                lValue = lValue >> 8
                If lValue = 0 Then Exit For
            Next


            If UIntHeadValue > 0 Then
                lValue = UIntHeadValue
                For i = 3 To 0 Step -1
                    bByte(i) = CByte(lValue And iAndValue)

                    lValue = lValue >> 8
                    If lValue = 0 Then Exit For
                Next
            End If
            Return bByte
        End Function

        ''' <summary>
        ''' 获取指定字节数的数组
        ''' </summary>
        ''' <param name="iLen"></param>
        ''' <returns></returns>
        Public Function toBytes(ByVal iLen As Integer) As Byte()
            Dim bByte() As Byte
            ReDim bByte(iLen - 1)

            Dim iAndValue As ULong = 255
            Dim lValue = UInt64Value
            Dim iEndIndex = 0
            If iLen > 8 Then
                iEndIndex = iLen - 8
            End If
            For i = iLen - 1 To iEndIndex Step -1
                bByte(i) = CByte(lValue And iAndValue)

                lValue = lValue >> 8
                If lValue = 0 Then Exit For
            Next


            If UIntHeadValue > 0 Then
                lValue = UIntHeadValue
                iEndIndex = 0
                Dim iIndex = iLen - 9
                iEndIndex = iIndex - 3
                If iEndIndex < 0 Then iEndIndex = 0
                For i = iIndex To iEndIndex Step -1
                    bByte(i) = CByte(lValue And iAndValue)

                    lValue = lValue >> 8
                    If lValue = 0 Then Exit For
                Next
            End If
            Return bByte
        End Function

        Public Sub setBytes(ByVal bByte() As Byte)

            Dim iAndValue As ULong = 255
            Dim lValue As ULong = 0
            Dim i As Integer, iLen As Integer
            Dim iIndex As Integer
            iLen = bByte.Length
            iIndex = 0
            If iLen > 8 Then iIndex = iLen - 8

            iLen = iLen - 1
            For i = iIndex To iLen
                lValue = lValue + bByte(i)
                If Not i = iLen Then
                    lValue = lValue << 8
                End If
            Next
            UInt64Value = lValue
            FloatDigit = 0
            Negative = 0

            iLen += 1
            If iLen > 8 Then
                iIndex = 0
                If iLen > 12 Then iIndex = iLen - 12
                iLen = iLen - 9
                lValue = 0
                For i = iIndex To iLen
                    lValue = lValue + bByte(i)
                    If Not i = iLen Then
                        lValue = lValue << 8
                    End If
                Next
                UIntHeadValue = lValue
            Else
                UIntHeadValue = 0
            End If
        End Sub


        Public Sub setBytes(ByVal bByte() As Byte, ByVal iBeginIndex As Integer, ByVal iByteCount As Integer)

            Dim iAndValue As ULong = 255
            Dim lValue As ULong = 0
            Dim i As Integer, iLen As Integer
            Dim iIndex As Integer
            iLen = iByteCount
            iIndex = 0
            If iLen > 8 Then iIndex = iLen - 8

            iLen = iLen - 1
            For i = iIndex To iLen
                lValue = lValue + bByte(iBeginIndex + i)
                If Not i = iLen Then
                    lValue = lValue << 8
                End If
            Next
            UInt64Value = lValue
            FloatDigit = 0
            Negative = 0

            iLen += 1
            If iLen > 8 Then
                iIndex = 0
                If iLen > 12 Then iIndex = iLen - 12
                iLen = iLen - 9
                lValue = 0
                For i = iIndex To iLen
                    lValue = lValue + bByte(iBeginIndex + i)
                    If Not i = iLen Then
                        lValue = lValue << 8
                    End If
                Next
                UIntHeadValue = lValue
            Else
                UIntHeadValue = 0
            End If
        End Sub


    End Structure



    ''' <summary>
    ''' 字节数组转长整形
    ''' </summary>
    ''' <param name="b">字节数组 1-8个元素</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function BytesToLong(ByVal b() As Byte) As UInt64
        Dim lValue As UInt64 = 0
        Dim i As Byte
        If b.Length > 8 Then Return 0
        If b.Length = 0 Then Return 0


        For i = 0 To b.GetUpperBound(0)
            lValue = lValue + b(i)
            If Not i = b.GetUpperBound(0) Then
                lValue = lValue << 8
            End If
        Next

        Return lValue
    End Function


    Public Function BytesToLong(ByVal b() As Byte, ByVal iBegin As Integer, ByVal iCount As Integer) As UInt64
        Dim lValue As UInt64 = 0
        Dim i As Byte
        If iCount > 8 Then iCount = 8
        If b.Length = 0 Then Return 0

        Dim iEndIndex = (iCount + iBegin) - 1
        For i = iBegin To iEndIndex
            lValue = lValue + b(i)
            If Not i = iEndIndex Then
                lValue = lValue << 8
            End If
        Next

        Return lValue
    End Function


    Public Function BytesToDecimal(ByVal b() As Byte, ByVal iBegin As Integer, ByVal iCount As Integer) As Decimal
        Dim lValue As Decimal = 0
        Dim i As Byte
        If iCount > 10 Then iCount = 10
        If b.Length = 0 Then Return 0

        Dim iEndIndex = (iCount + iBegin) - 1
        For i = iBegin To iEndIndex
            lValue = lValue + b(i)
            If Not i = iEndIndex Then
                lValue = lValue * 256
            End If
        Next

        Return lValue
    End Function


    Public Function DecimalToBytes(ByVal lValue As Decimal) As Byte()
        Dim b As BigInt
        b.BigValue = lValue
        Return b.toBytes
    End Function

    ''' <summary>
    ''' 将长整形转为字节数组
    ''' </summary>
    ''' <param name="lValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function LongToBytes(ByVal lValue As UInt64) As Byte()
        Dim b(7) As Byte
        Dim iAndValue As UInt64 = 255
        For i = 7 To 0 Step -1
            b(i) = CByte(lValue And iAndValue)

            lValue = lValue >> 8
            If lValue = 0 Then Exit For
        Next

        Return b
    End Function

    ''' <summary>
    ''' 字节转十六进制
    ''' </summary>
    ''' <param name="bData"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ByteToHex(ByVal bData() As Byte) As String
        Dim bHex() As Byte
        Dim i As Long, lIndex As Long
        If bData.Length = 0 Then Return "00"

        '初始化操作
        ReDim bHex(UBound(bData) * 2 + 1)

        '开始转换
        lIndex = 0
        For i = 0 To UBound(bData)
            bHex(lIndex) = mHexDigits(bData(i) \ 16) : lIndex = lIndex + 1
            bHex(lIndex) = mHexDigits(bData(i) Mod 16) : lIndex = lIndex + 1
        Next

        ByteToHex = gASCII.GetString(bHex)
    End Function


    Public Function ByteToHex(ByVal bData() As Byte, ByVal iBegin As Integer, ByVal iCount As Integer) As String
        Dim bHex() As Byte
        Dim i As Long, lIndex As Long
        If bData.Length = 0 Then Return "00"

        '初始化操作
        ReDim bHex(iCount * 2 - 1)

        '开始转换
        lIndex = 0
        Dim iEnd = (iBegin + iCount) - 1
        For i = iBegin To iEnd
            bHex(lIndex) = mHexDigits(bData(i) \ 16) : lIndex = lIndex + 1
            bHex(lIndex) = mHexDigits(bData(i) Mod 16) : lIndex = lIndex + 1
        Next

        ByteToHex = gASCII.GetString(bHex)
    End Function


    ''' <summary>
    ''' 十六进制转字节
    ''' </summary>
    ''' <param name="sHex"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function HexToByte(ByVal sHex As String) As Byte()
        '十六进制转字节
        Dim i As Long
        Dim bbuf() As Byte
        ReDim bbuf(0)
        If String.IsNullOrWhiteSpace(sHex) Then
            Return bbuf
        End If

        If Len(sHex) Mod 2 = 1 Then
            sHex = "0" & sHex
        End If

        If Len(sHex) = 0 Then
            Return bbuf
        End If

        '初始化操作
        If mByteDigits Is Nothing Then
            Dim bTmp() As Byte
            ReDim mByteDigits(255)
            bTmp = gASCII.GetBytes("0123456789ABCDEF")
            For i = 0 To UBound(bTmp)
                mByteDigits(bTmp(i)) = i
            Next
            bTmp = gASCII.GetBytes("abcdef")
            For i = 0 To UBound(bTmp)
                mByteDigits(bTmp(i)) = i + 10
            Next
        End If

        '开始转换
        bbuf = gASCII.GetBytes(sHex)
        Dim iData As Byte, lIndex As Long
        Dim bRtn() As Byte
        ReDim bRtn((UBound(bbuf) - 1) / 2)

        lIndex = 0
        For i = 0 To UBound(bbuf)
            iData = mByteDigits(bbuf(i)) * 16 '高位
            i = i + 1
            iData = iData + mByteDigits(bbuf(i)) '低位
            bRtn(lIndex) = iData
            lIndex = lIndex + 1
        Next
        HexToByte = bRtn
    End Function

    ''' <summary>
    ''' 字节转Bit
    ''' </summary>
    ''' <param name="iNum"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ByteToBit(ByVal iNum As Byte) As Byte()
        Dim bList As BitArray = New BitArray({iNum})
        Dim iBit(7) As Byte, iIndex As Byte = 0

        For Each bValue As Boolean In bList
            iBit(iIndex) = IIf(bValue, 1, 0)

            iIndex += 1
        Next

        Return iBit
    End Function

    ''' <summary>
    ''' Bit转字节
    ''' </summary>
    ''' <param name="iBits">存储位数据的8元素数组</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function BitToByte(ByVal iBits() As Byte) As Byte
        Dim bList As BitArray = New BitArray(8)
        Dim iValue() As Byte = {0}
        For i As Byte = 0 To 7
            bList(i) = (iBits(i) = 1)
        Next
        '将bit数组转换为字节
        bList.CopyTo(iValue, 0)
        Return iValue(0)
    End Function

    ''' <summary>
    ''' 字节转BCD码
    ''' </summary>
    ''' <param name="iNum"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ByteToBCDNUM(ByVal iNum As Byte) As Byte
        'Return Byte.Parse(iNum.ToString, Globalization.NumberStyles.HexNumber)
        Return (iNum \ 10) * 16 + (iNum Mod 10)
    End Function

    ''' <summary>
    ''' 字节转BCD码
    ''' </summary>
    ''' <param name="iNum"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ByteToBCDNUM(ByVal iNum() As Byte) As Byte()
        For i As Integer = 0 To iNum.Length - 1
            iNum(i) = (iNum(i) \ 10) * 16 + (iNum(i) Mod 10)
        Next
        Return iNum
    End Function

    ''' <summary>
    ''' BCD转字节值
    ''' </summary>
    ''' <param name="iNum"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function BCDToByte(ByVal iNum As Byte) As Byte
        Return ((iNum \ 16) * 10) + (iNum Mod 16)
    End Function

    ''' <summary>
    ''' BCD转字节值
    ''' </summary>
    ''' <param name="iNum"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function BCDToByte(ByVal iNum() As Byte) As Byte()
        For i As Integer = 0 To iNum.Length - 1
            iNum(i) = ((iNum(i) \ 16) * 10) + (iNum(i) Mod 16)
        Next
        Return iNum
    End Function

    Public Function BCDToDateYYMMdd(ByVal bData() As Byte) As Date
        bData = BCDToByte(bData)
        If bData(0) > 99 Or bData(0) = 0 Then
            Return Date.MinValue
        End If

        If bData(1) > 12 Or bData(1) = 0 Then
            Return Date.MinValue
        End If

        If bData(2) > 31 Or bData(2) = 0 Then
            Return Date.MinValue
        End If

        Return New Date(CInt(bData(0)) + 2000, bData(1), bData(2))
    End Function

    Public Function BCDToDateYYMMddHHmm(ByVal bData() As Byte, ByVal iBegin As Integer) As Date
        Dim iYear As Integer, iMonth As Integer, iDay As Integer
        Dim iHour As Integer, iMinute As Integer
        iYear = BCDToByte(bData(iBegin)) : iBegin += 1
        iMonth = BCDToByte(bData(iBegin)) : iBegin += 1
        iDay = BCDToByte(bData(iBegin)) : iBegin += 1
        iHour = BCDToByte(bData(iBegin)) : iBegin += 1
        iMinute = BCDToByte(bData(iBegin))
        If iYear > 99 Or iYear = 0 Then
            Return Date.MinValue
        End If

        If iMonth > 12 Or iMonth = 0 Then
            Return Date.MinValue
        End If

        If iDay > 31 Or iDay = 0 Then
            Return Date.MinValue
        End If

        If iHour > 23 Then
            Return Date.MinValue
        End If

        If iMinute > 59 Then
            Return Date.MinValue
        End If


        Return New Date(iYear + 2000, iMonth, iDay, iHour, iMinute, 59)
    End Function

    Public Function BCDToTimeHHmmss(ByVal bData() As Byte) As Date
        bData = BCDToByte(bData)
        If bData(0) > 23 Or bData(0) = 0 Then
            Return Date.MinValue
        End If

        If bData(1) > 59 Or bData(1) = 0 Then
            Return Date.MinValue
        End If

        If bData(2) > 59 Or bData(2) = 0 Then
            Return Date.MinValue
        End If

        Return New Date(2017, 1, 1, bData(0), bData(1), bData(2))
    End Function

    ''' <summary>
    ''' 无符号8位整形，转换为有符号8位整形。
    ''' </summary>
    ''' <param name="bValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ByteToSByte(ByVal bValue As Byte) As SByte
        Dim bNum As SByte
        bNum = 0
        If bValue > 128 Then
            bNum = -(128 - (bValue - 128))
        ElseIf bValue = 128 Then
            bNum = -128
        Else
            bNum = bValue
        End If
        Return bNum

        'Return SByte.Parse(bValue.ToString("X2"), Globalization.NumberStyles.HexNumber)
    End Function

    ''' <summary>
    ''' 有符号8位整形，转换为无符号8位整形。
    ''' </summary>
    ''' <param name="b"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SBytetobyte(ByVal b As SByte) As Byte
        Dim bNum As Byte

        If b < 0 Then
            If b = -128 Then
                bNum = 128
            Else
                bNum = -b
                bNum = (128 - bNum) + 128
            End If

        Else
            bNum = b
        End If

        Return bNum
    End Function



    ''' <summary>
    ''' 字节数组转短整型 Int16 高位在前
    ''' </summary>
    ''' <param name="bData"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ByteToInt16(ByVal bData() As Byte) As UShort
        Dim iValue As UInt16 = bData(0)
        iValue = (iValue << 8) + bData(1)
        Return iValue
    End Function

    Public Function ByteToInt16(ByVal bData() As Byte, ByVal iBeginIndex As Integer) As UShort
        Dim iValue As UInt16 = bData(iBeginIndex)
        iValue = (iValue << 8) + bData(iBeginIndex + 1)
        Return iValue
    End Function


    ''' <summary>
    ''' 字节数组转 Int32 整形 高位在前
    ''' </summary>
    ''' <param name="bData"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ByteToInt32(ByVal bData() As Byte) As UInt32
        If bData Is Nothing Then Return 0
        Dim iValue As UInt32 = 0
        Dim iLen As Byte = (bData.Length - 1)
        For i As Byte = 0 To iLen
            iValue = iValue << 8
            iValue += bData(i)
            If i = 3 Then Exit For
        Next
        Return iValue
    End Function


    Public Function ByteToInt32(ByRef bData() As Byte, ByVal iBeginIndex As Integer, ByVal iLen As Integer) As UInt32
        Dim iValue As UInt32 = 0
        If iLen > 4 Then iLen = 4

        For i = 0 To iLen - 1
            iValue = iValue << 8
            iValue += bData(iBeginIndex + i)
        Next
        Return iValue
    End Function


    ''' <summary>
    ''' 字节数组转 Int32 整形 低位在前
    ''' </summary>
    ''' <param name="bData"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ByteToInt32Rev(ByVal bData() As Byte) As UInt32
        Dim b = bData.Clone
        Array.Reverse(b)
        Dim iValue As UInt32 = 0
        For i As Byte = 0 To b.Length - 1
            iValue = iValue << 8
            iValue += b(i)
            If i = 3 Then Exit For
        Next
        Return iValue
    End Function

    ''' <summary>
    ''' Int32 整形 转 字节数组 高位在前
    ''' </summary>
    ''' <param name="iValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Int32ToByte(ByVal iValue As UInt32) As Byte()
        Dim b(3) As Byte
        Dim iAndValue As UInt32 = 255
        For i = 3 To 0 Step -1
            b(i) = CByte(iValue And iAndValue)

            iValue = iValue >> 8
            If iValue = 0 Then Exit For
        Next

        Return b

    End Function

    ''' <summary>
    ''' Int32 整形 转 字节数组 低位在前
    ''' </summary>
    ''' <param name="iValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Int32ToByteRev(ByVal iValue As UInt32) As Byte()
        Dim b(3) As Byte
        For i = 0 To 3
            b(i) = iValue And 255

            iValue = iValue >> 8
            If iValue = 0 Then Exit For
        Next

        Return b
    End Function


    ''' <summary>
    ''' Int32 整形 转 字节数组 高位在前
    ''' </summary>
    ''' <param name="iValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Int32To3Byte(ByVal iValue As UInt32) As Byte()
        Dim b(2) As Byte
        For i = 2 To 0 Step -1
            b(i) = iValue And 255

            iValue = iValue >> 8
            If iValue = 0 Then Exit For
        Next

        Return b
    End Function

    ''' <summary>
    ''' Int32 整形 转 字节数组 高位在前
    ''' </summary>
    ''' <param name="iValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Int32To2Byte(ByVal iValue As Int32) As Byte()
        Dim b(1) As Byte
        For i = 1 To 0 Step -1
            b(i) = iValue And 255

            iValue = iValue >> 8
            If iValue = 0 Then Exit For
        Next

        Return b
    End Function

    ''' <summary>
    ''' Int16 整形 转 字节数组  高位在前
    ''' </summary>
    ''' <param name="iValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Int16ToByte(ByVal iValue As UInt16) As Byte()
        Dim b(1) As Byte
        b(1) = iValue Mod 256
        iValue = iValue >> 8
        b(0) = iValue Mod 256
        Return b
    End Function


    Public Sub Int16ToByte(ByVal iValue As UInt16, ByVal bBuf() As Byte, ByVal offset As Integer)
        bBuf(offset + 1) = iValue Mod 256
        iValue = iValue >> 8
        bBuf(offset) = iValue Mod 256
    End Sub


    ''' <summary>
    ''' 拷贝数组
    ''' </summary>
    ''' <param name="src">源数组，从此数组中取数据</param>
    ''' <param name="iBegin">开始截取数组的起始索引，从0开始。</param>
    ''' <param name="lLen">截取数组元素的长度。</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function copyOfRange(ByVal src() As Byte, ByVal iBegin As Integer, ByVal lLen As Integer) As Byte()
        Return Arrays(Of Byte).copyOfRange(src, iBegin, lLen)
    End Function


    ''' <summary>
    ''' 检查字符串是否为指定长度
    ''' </summary>
    ''' <param name="sValue">待检查字符串</param>
    ''' <param name="iLength">需要的长度</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CheckStringLen(ByVal sValue As String, ByVal iLength As Integer, Optional ByVal sNullString As String = " ") As String
        If (String.Equals(sValue, String.Empty)) Then
            sValue = New String(sNullString, iLength)
        End If
        If sValue.Length > iLength Then
            sValue = sValue.Substring(0, iLength)
        End If
        If sValue.Length < iLength Then
            sValue = sValue & New String(sNullString, iLength - sValue.Length)
        End If
        Return sValue
    End Function

    ''' <summary>
    ''' 检查字符串是否为十六进制
    ''' </summary>
    ''' <param name="sValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsHex(ByVal sValue As String) As Boolean
        If (String.Equals(sValue, String.Empty)) Then
            Return False
        End If
        sValue = sValue.ToUpper()
        Dim sFormat As String = "1234567890ABCDEF"
        For i As Integer = 0 To sValue.Length - 1
            If InStr(sFormat, sValue.Substring(i, 1)) = 0 Then
                Return False
            End If
        Next
        Return True
    End Function


    ''' <summary>
    ''' 检查字符串是否为十进制
    ''' </summary>
    ''' <param name="sValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsNum(ByVal sValue As String) As Boolean
        If (String.Equals(sValue, String.Empty)) Then
            Return False
        End If
        sValue = sValue.ToUpper()
        Dim sFormat As String = "1234567890"
        For i As Integer = 0 To sValue.Length - 1
            If InStr(sFormat, sValue.Substring(i, 1)) = 0 Then
                Return False
            End If
        Next
        Return True
    End Function


    ''' <summary>
    ''' 检查十六进制字符串格式及长度
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CheckHexLen(ByVal sHex As String, ByVal iLen As Integer) As String
        sHex = sHex.ToUpper
        If sHex.Length > iLen Then
            sHex = sHex.Substring(0, iLen)
        End If

        If sHex.Length < iLen Then
            sHex = sHex & New String("F", iLen - sHex.Length)
        End If

        If Not IsHex(sHex) Then
            sHex = New String("F", iLen)
        End If

        Return sHex
    End Function

    ''' <summary>
    ''' 检查输入的缓冲区长度是否达到指定最大值
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CheckBuffLen(ByVal bBuf() As Byte, ByVal iMax As Integer) As Byte()

        If bBuf Is Nothing Then
            Dim b() As Byte
            ReDim b(iMax - 1)
            Return b
        End If
        If bBuf.Length = iMax Then Return bBuf

        If bBuf.Length > iMax Then
            bBuf = copyOfRange(bBuf, 0, iMax)
        ElseIf bBuf.Length < iMax Then
            Dim bList = New List(Of Byte)
            bList.Capacity = iMax
            bList.AddRange(bBuf)
            Dim b() As Byte
            ReDim b(iMax - bBuf.Length - 1)
            bList.AddRange(b)
            bBuf = bList.ToArray
            bList = Nothing
        End If
        Return bBuf
    End Function

    Public Function ReplaceEx(ByVal sSur As String, ByVal sValue() As String) As String
        Return ReplaceEx(sSur, "%1,%2,%3,%4,%5,%6,%7,%8,%9,%A,%B,%C,%D,%E,%F,%G,%H,%I,%J,%K,%L,%M,%N,%O,%P,%Q,%R,%S,%T,%U,%V,%W,%X,%Y,%Z", sValue)
    End Function

    Public Function ReplaceEx(ByVal sSur As String, ByVal sExKeyList As String, ByVal sValue() As String) As String
        Dim i As Long
        Dim sExKey() As String
        sExKey = Split(sExKeyList, ",")

        For i = 0 To sValue.GetUpperBound(0)
            If i > sExKey.GetUpperBound(0) Then Exit For
            sSur = sSur.Replace(sExKey(i), sValue(i))
        Next
        Return sSur
    End Function




    ''' <summary>
    ''' 显示调试输出
    ''' </summary>
    ''' <param name="sText"></param>
    ''' <remarks></remarks>
    Public Sub ShowDebugText(ByVal sText As String)

        '---------------------------
        Dim path As String = "d:\log.txt"
        Dim sw As IO.StreamWriter

        ' This text is added only once to the file.
        If IO.File.Exists(path) = False Then
            ' Create a file to write to.
            sw = IO.File.CreateText(path)
            sw.Close()
        End If

        ' This text is always added, making the file longer over time
        ' if it is not deleted.
        sw = IO.File.AppendText(path)
        sw.WriteLine(sText)
        sw.Flush()
        sw.Close()
    End Sub


    Public Sub StrToBuf(ByVal sStr As String, ByVal bBuf() As Byte)
        If String.IsNullOrEmpty(sStr) Then
            Array.Clear(bBuf, 0, bBuf.Length)
            Return
        End If
        Dim bTmp = gEncDefault.GetBytes(sStr)
        Dim iLen = bTmp.Length
        If iLen > bBuf.Length Then iLen = bBuf.Length
        Array.Clear(bBuf, 0, bBuf.Length)
        Array.Copy(bTmp, bBuf, iLen)
    End Sub

    Public Function BufToStr(ByVal bBuf() As Byte) As String
        Dim iEndIndex As Integer = 0
        For index = 0 To bBuf.Length - 1
            If bBuf(index) = 0 Then
                iEndIndex = index
                Exit For
            End If
        Next
        If iEndIndex = 0 Then Return String.Empty
        Dim btmp() As Byte
        ReDim btmp(iEndIndex - 1)
        Array.Copy(bBuf, btmp, iEndIndex)
        Return gEncDefault.GetString(btmp)
    End Function


    Public Sub HEXToBuf(ByVal sStr As String, ByVal bBuf() As Byte)
        Dim bTmp = HexToByte(sStr)
        Dim iLen = bTmp.Length
        If iLen > bBuf.Length Then iLen = bBuf.Length
        Array.Clear(bBuf, 0, bBuf.Length)
        Array.Copy(bTmp, bBuf, iLen)

    End Sub

    Public Function BufToHEX(ByVal bBuf() As Byte, ByVal iLen As Integer) As String
        Dim iEndIndex As Integer = iLen
        If iEndIndex = 0 Then Return String.Empty
        Dim btmp() As Byte
        ReDim btmp(iEndIndex - 1)
        Array.Copy(bBuf, btmp, iEndIndex)
        Return ByteToHex(btmp)
    End Function

    Public Function BoolToByte(ByVal b As Boolean) As Byte
        If (b) Then
            Return 1
        Else
            Return 0
        End If

    End Function

    Public Function BoolToByte(ByVal bDoors() As Boolean) As Byte()
        Dim iByte() As Byte
        Dim iLen = bDoors.Length - 1
        ReDim iByte(iLen)
        For i = 0 To iLen
            If bDoors(i) Then
                iByte(i) = 1
            End If

        Next
        Return iByte
    End Function

    Public Function ByteToBool(ByVal b As Byte) As Boolean
        Return Not (b = 0)

    End Function


#Region "BCD时间转换"



    ''' <summary>
    ''' 获取bcd格式时间   格式：ssmmHHddMMWWyy
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function DateToBCD(ByVal oDate As Date) As Byte()
        Dim bData(6), bbuf() As Byte
        Dim sHex As String
        sHex = Format(oDate, "yyMMddHHmmss")
        bbuf = ModTool.HexToByte(sHex)
        Array.Reverse(bbuf)
        Array.Copy(bbuf, bData, 6)
        bData(6) = bData(5)
        bData(5) = CByte(Weekday(oDate, FirstDayOfWeek.Monday)) '周
        Return bData
    End Function

    Public Function DateToBCDYYMMdd(ByVal oDate As Date) As Byte()
        Dim bData() As Byte
        If oDate.Equals(Date.MinValue) Then
            ReDim bData(2)
            Return bData
        Else
            bData = {oDate.Year - 2000, oDate.Month, oDate.Day}
        End If

        Return ByteToBCDNUM(bData)

    End Function
#End Region



End Module


Public Class Arrays(Of T)
    ''' <summary>
    ''' 拷贝数组
    ''' </summary>
    ''' <param name="src">源数组，从此数组中取数据</param>
    ''' <param name="iBegin">开始截取数组的起始索引，从0开始。</param>
    ''' <param name="lLen">截取数组元素的长度。</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function copyOfRange(ByVal src() As T, ByVal iBegin As Integer, ByVal lLen As Integer) As T()
        Dim bTmp() As T
        ReDim bTmp(lLen - 1)
        Array.Copy(src, iBegin, bTmp, 0, lLen)
        Return bTmp
    End Function



    ''' <summary>
    ''' 检查两个数组是否匹配
    ''' </summary>
    ''' <param name="src"></param>
    ''' <param name="sDec"></param>
    ''' <returns>true--匹配；false--不匹配</returns>
    ''' <remarks></remarks>
    Public Shared Function BytesEquals(ByVal src() As T, ByVal sDec() As T) As Boolean
        'Dim bret As List(Of T) = New List(Of T)
        Dim iCount As Integer = 0
        If src Is Nothing Then
            If sDec Is Nothing Then
                Return True
            Else
                Return False
            End If
        End If

        If sDec Is Nothing Then
            If src Is Nothing Then
                Return True
            Else
                Return False
            End If
        End If

        Dim i As Integer
        For i = 0 To src.Length - 1
            If Not src(i).Equals(sDec(i)) Then
                iCount += 1
                Exit For
            End If
        Next

        If iCount = 0 Then
            Return True
        Else
            Return False
        End If

    End Function
End Class
